from IPython.display import HTML
HTML('''<script>
code_show=true;
function code_toggle() {
if (code_show){
$('div.input').hide();
} else {
$('div.input').show();
}
code_show = !code_show
}
$( document ).ready(code_toggle);
</script>
<form action="javascript:code_toggle()"><input type="submit" value="Click here to toggle on/off the raw code."></form>''')
22-03-2020 4:00 p.m a 23-03-2020 05:30 a.m
Construí una red que representa las interacciones de los usuarios de Twitter que publican tuits con los hashtags "simulacrovital","bogotasequedaencasa","simulacrodeaislamiento","cuarentenaobligatoria bogota", "cuarentenaobligatoria bogotá","yomequedoencasa bogota","yomequedoencasa bogotá","quedateencasa bogotá", "quedateencasa bogota" y descargué los tuits asociados al tema. Con métodos de análisis de redes y text mining detecté los influenciadores y temas más importantes en esta conversación. Este ejercicio puede replicarse monitoreando cualquier otra palabra clave, hashtag o usuario.
Revisé los posts en Facebook e Instagram con más interacciones que incluyen la palara Bogotá y fueron realizados en el periodo de tiempo analizado. Este ejercicio se realizó con CrowdTangle.
DISCLAIMER: Este archivo se escribe en 15 minutos. Me disculpo por posibles errores de redacción y ortografía.
En Twitter la conversación gira en torno a la mejora de la calidad del aire, el cuidado de animales sin hogar y la difusión de información oficial de la alcaldía.
Hay dos comunidades pequeñas, pero con más de 5% de los nodos, que cuestionan (sin criticar directamente) el simulacro replicando mensajes de fuentes no oficiales (@penalosadas o @bogota__dc, por ejemplo)y de figuras públicas como Petro y Morris.
import json
from bson.json_util import dumps, CANONICAL_JSON_OPTIONS
from bson import Binary, Code
from collections import Counter, OrderedDict
import pyperclip
import spacy
from wordcloud import WordCloud
from stop_words import get_stop_words
import string
import altair as alt
import matplotlib.pyplot as plt
nlp=spacy.load('es_core_news_sm')
import pandas as pd
stopwords_es= get_stop_words('es')
import pandas as pd
import networkx as nx
import numpy as np
import matplotlib.pyplot as plt
import collections
import tweepy
import csv
import operator
import community
from IPython.display import Markdown,display
from datetime import datetime
import dateutil
from pymongo import MongoClient
client = MongoClient()
db = client.corona
G=nx.read_graphml("/home/laufernanda/Documents/corona-redes/simulacro8.graphml")
print('La red tiene ',G.number_of_nodes(),'usuarios y ',G.number_of_edges(),"interacciones")
from IPython.display import Image
Image(filename='image8.png')
G= nx.DiGraph(G)
#centrality = nx.eigenvector_centrality(G)
for node in G.nodes():
G.nodes[node]["in_degree"]=G.in_degree[node]
G.nodes[node]["out_degree"]=G.out_degree[node]
#G.nodes[node]["eigenvector"]=centrality[node]
H=G.to_undirected()
partition=community.best_partition(H)
for node in G.nodes() :
G.node[node]['comunidad']= partition[node]
#Análisis comunidades
#Tamano comunidades
c=Counter(list(partition.values()))
c=OrderedDict(c.most_common())
n=G.number_of_nodes()/20
comunidades_importantes=[]
for k in c.keys():
if c[k]>= n:
comunidades_importantes.append(k)
print("La red tiene ", len(comunidades_importantes), " comunidades importantes (tienen más del 5% de los nodos)" )
top_reacciones={}
top_creadores={}
top_influencers={}
grado_in=sorted(G.in_degree(),key=operator.itemgetter(1),reverse=True)
for comunidad in comunidades_importantes:
nodos_comunidad=[node for node in G.nodes() if G.nodes[node]['comunidad']==comunidad]
grado_in=sorted(G.in_degree(nodos_comunidad),key=operator.itemgetter(1),reverse=True)
grado_out=sorted(G.out_degree(nodos_comunidad),key=operator.itemgetter(1),reverse=True)
eigen={k:v for k,v in centrality.items() if k in nodos_comunidad}
eigen=sorted(eigen,key=operator.itemgetter(1),reverse=True)
top_reacciones[comunidad]=[x[0] for x in grado_in[0:5]]
top_creadores[comunidad]=[x[0] for x in grado_out[0:5]]
top_influencers[comunidad]=eigen[0:5]
De la comunidad con más nodos (usuarios) a la de menos:
(Verde en la gráfica) Es una comunidad de difusión de los resultados positivos de calidad del aire.También contiene la difusión de las indicaciones de la alcaldía para retornar a Bogotá.
(Azul en la gráfica) Es una comunidad de difusión de información oficial regional (Cundinamarca-Bogotá) enfocada en el plan retorno para quienes salieron de Bogotá.La cuenta del gobernador de Cundinamarca, la alcaldía y la W Radio son las más visibles. Uno de los tuits populares pide sanciones a quienes salieron.
(Rojo en la gráfica )Es una comunidad de Preocupación ciudadana por el bienestar de los animales. Solicitan vigilancia en las Plazas de mercado de la ciudad y apoyo para protección de animales sin hogar.
import pytz
start = datetime(2020, 3, 22, 21, 00, 00, 0, pytz.UTC)
end = datetime(2020, 3, 23, 10, 30, 00, 0, pytz.UTC)
count=0
for comunidad in comunidades_importantes:
count+=1
display(Markdown(str("## Comunidad "+ str(count) + ":")))
display(Markdown(str("**La comunidad "+ str(count)+ " tiene "+ str(c[comunidad])+" usuarios**")))
display(Markdown(str("**La comunidad "+ str(count)+ " habla de:**")))
nodos_comunidad=[node for node in G.nodes() if G.nodes[node]['comunidad']==comunidad]
nodos_comunidad=[sub.replace('@', '') for sub in nodos_comunidad]
tw_iter=db.simulacro.find({"user.screen_name":{"$in":nodos_comunidad}})
text=[]
ids_filtrados=[]
for tweet in tw_iter:
tw=tweet
date_tuit=dateutil.parser.parse(tw["created_at"])
if(start<date_tuit< end):
ids_filtrados.append(tw['_id'])
text.append(tweet["text"])
if len(text)>=1:
text_s=" ".join(text)
text_s=text_s.replace("https"," ")
text_s=text_s.replace("RT"," ")
wordcloud = WordCloud(scale=2, max_words=2000,relative_scaling=0.5,background_color ='white',stopwords=stopwords_es).generate(text_s)
plt.imshow(wordcloud)
plt.axis("off")
plt.show()
print("Se incluyeron ",len(text), "tuits producidos por nodos de esta comunidad en el intervalo de tiempo analizado.")
display(Markdown(str("**los usuarios que son más retuiteados, mencionados o citados en la comunidad "+ str(count) + " son:**"+
", ".join(top_reacciones[comunidad]))))
print("__________________________________________________________________________________________________________________")
display(Markdown(str("**los usuarios que retuitean, mencionan y citan más en la comunidad "+ str(count) + " son:**"+
", ".join(top_creadores[comunidad]))))
#print("__________________________________________________________________________________________________________________")
#display(Markdown(str("**los usuarios con mayor influencia en la comunidad "+ str(comunidad) + " son:**"+
# ", ".join(top_influencers[comunidad]))))
#print("__________________________________________________________________________________________________________________")
display(Markdown(str("**los trinos más retuiteados de la comunidad "+ str(count) + " son:**")))
nodos_comunidad=[node for node in G.nodes() if G.nodes[node]['comunidad']==comunidad]
nodos_comunidad=[sub.replace('@', '') for sub in nodos_comunidad]
#Top most retweeted tweets
tw_iter_RT = db.simulacro.aggregate([
{"$match": {
"$and":[ {"retweeted_status": {"$exists": True}},
{"_id":{"$in":ids_filtrados}}
]}},
{"$replaceRoot": { "newRoot": "$retweeted_status" }},
{"$group" : {"_id":"$id",
"text":{"$last":"$extended_tweet.full_text"},
"username":{"$last":"$user.screen_name"},
"count":{"$sum":1}}},
{"$sort": {"count": -1}}
])
try:
top = [tw_iter_RT.next() for i in range(10)]
df= pd.DataFrame(top)
pd.set_option("max_colwidth",300)
display(df)
except:
top = list(tw_iter_RT)
df= pd.DataFrame(top)
display(df)
print("no hay suficiente info disponible")
display(Markdown(str("**los hashtags más usados en la comunidad "+ str(count) + " son:**")))
#Hashtgas
#Top most used hashtags
tw_iter_HT = db.simulacro.aggregate([
{"$match":{"_id":{"$in":ids_filtrados}}},
{"$unwind": "$entities.hashtags"},
{"$group" : {"_id":"$entities.hashtags.text",
"count":{"$sum":1}}},
{"$sort": {"count": -1}}
])
try:
top = [tw_iter_HT.next() for i in range(5)]
df= pd.DataFrame(top)
display(df)
except:
top = list(tw_iter_HT)
df= pd.DataFrame(top)
display(df)
print("no hay suficiente info disponible")
display(Markdown(str("## Los post de Facebook con la palabra Bogotá que más interacciones tuvieron en este periodo de tiempo fueron:")))
Image(filename='./8_Facebook.png')
display(Markdown(str("## Los post de Instagram con la palabra Bogotá que más interacciones tuvieron en este periodo de tiempo fueron")))
Image(filename='./8_Instagram.png')
usuarios_importantes=[]
for comunidad in comunidades_importantes:
usuarios_importantes.extend(top_reacciones[comunidad])
usuarios_importantes.extend(top_creadores[comunidad])
#usuarios_importantes.extend(top_influencers[comunidad])
usuarios_importantes=set(usuarios_importantes)
f = open("./twitteros_importantes_conversación_simulacro2.txt", "a")
for line in usuarios_importantes:
f.write(line)
f.write("\n")
print(line)
f.close()